bl_info = {
    "name": "UV-utils",
    "author": "会飞的键盘侠",
    "blender": (2, 90, 0),
    "version": (1, 0, 0)
}
import bpy
import bmesh

bm = []


def compute_polygon_area(points):
    point_num = len(points)
    s = points[0][1] * (points[point_num - 1][0] - points[1][0])
    for i in range(1, point_num):
        s += points[i][1] * (points[i - 1][0] - points[(i + 1) % point_num][0])
    return abs(s / 2.0)


def update_uv_list():
    bpy.context.scene.fit.clear()
    for b in bm:
        if not b.is_valid:
            continue
        uv_layer = b.loops.layers.uv.active
        for bf in b.faces:
            for loop in bf.loops:
                if not loop[uv_layer].select:
                    break
            else:
                it = bpy.context.scene.fit.add()
                area_list = []
                for bfl in bf.loops:
                    iit = it.co.add()
                    iit.uv = bfl[uv_layer].uv
                    area_list.append(bfl[uv_layer].uv)
                it.area = compute_polygon_area(area_list)
    return 0.1


class Co_Item(bpy.types.PropertyGroup):
    uv: bpy.props.FloatVectorProperty(size=2, name="UV坐标")


class Co_Items(bpy.types.PropertyGroup):
    co: bpy.props.CollectionProperty(type=Co_Item)
    area: bpy.props.FloatProperty()


Face_Items = bpy.props.CollectionProperty(type=Co_Items)


class UV_Ops1(bpy.types.Operator):
    bl_idname = "eg.uvops1"
    bl_label = "操作符1"

    @classmethod
    def poll(self, context):
        return context.area.ui_type == "UV"

    def execute(self, context):
        if bpy.context.mode == "EDIT_MESH":
            res = bmesh.from_edit_mesh(bpy.context.object.data)
            for b in bm:
                b.free()
            bm.clear()
            bm.append(res)

        return {"FINISHED"}


class UV_Ops2(bpy.types.Operator):
    bl_idname = "eg.uvtomesh"
    bl_label = "UV 转 网格"
    char_list = [str(i) for i in range(10)] + ['a', 'b', 'c', 'd', 'e', 'f']

    def random_name(self):
        import random
        return "".join(random.choices(self.char_list, k=10))

    @classmethod
    def poll(self, context):
        return context.area.ui_type == "UV"

    def execute(self, context):
        if bpy.context.mode == "EDIT_MESH":
            bm = bmesh.from_edit_mesh(bpy.context.object.data)
            uv_layer = bm.loops.layers.uv.active
            for face in bm.faces:
                me = bpy.data.meshes.new(name=self.random_name())
                vertices = []
                for loop in face.loops:
                    vertices.append((*loop[uv_layer].uv[:], 0))
                edges = [(0, 1), (1, 2), (2, 3), (3, 0)]
                face = [(0, 1, 2, 3)]
                me.from_pydata(vertices=vertices, edges=edges, faces=face)
                obj = bpy.data.objects.new(name=me.name, object_data=me)
                bpy.context.collection.objects.link(obj)
            bm.free()

        return {"FINISHED"}


class UV_Panel(bpy.types.Panel):
    bl_region_type = "UI"
    bl_space_type = "IMAGE_EDITOR"
    bl_category = "UV-utils"
    bl_idname = "UV_PT_utils"
    bl_label = "UV-utils"

    @classmethod
    def poll(self, context):
        return context.area.ui_type == "UV"

    def draw(self, context):
        layout = self.layout
        layout.operator(UV_Ops2.bl_idname)
        layout.operator(UV_Ops1.bl_idname)
        # layout.prop(bpy.context.scene.eg2, "uv")
        fit = bpy.context.scene.fit
        for it in fit:
            row = layout.row()
            for iit in it.co:
                row.prop(iit, "uv", text="")
            row.prop(it, "area")


clss = [UV_Panel, UV_Ops1, UV_Ops2, Co_Item, Co_Items]


def register():
    for cls in clss:
        bpy.utils.register_class(cls)
    bpy.types.Scene.fit = Face_Items
    bpy.app.timers.register(update_uv_list)


def unregister():
    for cls in clss:
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.fit
    bpy.app.timers.unregister(update_uv_list)
